package com.cloud.system.api.service.impl;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cloud.system.api.bean.HumanRoleForm;
import com.cloud.system.api.bean.HumanRoleResourcesForm;
import com.cloud.system.api.entity.HumanInfo;
import com.cloud.system.api.entity.HumanRole;
import com.cloud.system.api.entity.RoleInfo;
import com.cloud.system.api.entity.RoleResources;
import com.cloud.system.api.entity.UnitInfo;
import com.cloud.system.api.mapper.HumanInfoMapper;
import com.cloud.system.api.mapper.HumanRoleMapper;
import com.cloud.system.api.mapper.RoleInfoMapper;
import com.cloud.system.api.mapper.RoleResourcesMapper;
import com.cloud.system.api.mapper.UnitInfoMapper;
import com.cloud.system.api.service.RoleInfoService;
import com.cloud.system.common.result.QkTreeNode;
import com.cloud.system.common.result.Quokka;
import com.cloud.system.common.utils.RedisKeyHelper;
import com.cloud.system.common.utils.SessionHelper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import tk.mybatis.mapper.entity.Example;

@Service
@Transactional
public class RoleInfoServiceImpl implements RoleInfoService {

	@Autowired
	private RoleInfoMapper roleInfoMapper;
	@Autowired
	private UnitInfoMapper unitInfoMapper;
	@Autowired
	private HumanRoleMapper humanRoleMapper;
	@Autowired
	private RoleResourcesMapper humanRoleResourcesMapper;
	@Autowired
	private HumanInfoMapper humanInfoMapper;
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	@Override
	public List<QkTreeNode> listRoleTree(long unitId, boolean isRoot) {
		List<Integer> unitTypeIDs = new ArrayList<>();
		unitTypeIDs.add(5);
		unitTypeIDs.add(2);
		unitTypeIDs.add(4);

		List<QkTreeNode> nodes = new ArrayList<QkTreeNode>();
		QkTreeNode rootNode = null;
		UnitInfo rootUnit = null;
		if (isRoot) {
			if (unitId != 0) {
				rootUnit = unitInfoMapper.selectByPrimaryKey(unitId);
			} else {
				rootUnit = unitInfoMapper.selectByPrimaryKey(SessionHelper.get().getUnitId()); 
			}
			rootNode = new QkTreeNode(rootUnit.getUnitId(), rootUnit.getUnitName());
			rootNode.setSelectable(true);
			rootNode.setIcon("fa fa-university");
			rootNode.getData().put("code", rootUnit.getUnitCode());
			rootNode.getData().put("type", "U");
			rootNode.setExpanded(true);
		}
		if (null != rootNode) {
			nodes.add(rootNode);
		}
		// 加载机构下的岗位
		List<QkTreeNode> roles = new ArrayList<QkTreeNode>();
		Example roleExample = new Example(RoleInfo.class);
		Example.Criteria roleCriteria = roleExample.createCriteria();
		roleCriteria.andEqualTo("unitId", null != rootUnit ? rootUnit.getUnitId() : unitId);
		roleExample.orderBy("displayOrder").asc();
		List<RoleInfo> roleLists = roleInfoMapper.selectByExample(roleExample);
		if (null != roleLists && roleLists.size() > 0) {
			for (RoleInfo i : roleLists) {
				QkTreeNode node = new QkTreeNode(i.getRoleId(), i.getRoleName());
				node.setIcon("fa fa-user-circle-o");
				node.setSelectable(true);
				node.setLeaf(true);
				node.getData().put("code", i.getUnitCode() + i.getRoleId() + "/");
				node.getData().put("type", "R");
				roles.add(node);
			}
		}
		// 加载下级机构
		List<QkTreeNode> childrens = new ArrayList<QkTreeNode>();
		Example unitExample = new Example(UnitInfo.class);
		Example.Criteria unitCriteria = unitExample.createCriteria();
		unitCriteria.andNotEqualTo("deleteFlag", 1);
		unitCriteria.andEqualTo("seniorId", null != rootUnit ? rootUnit.getUnitId() : unitId);
		unitExample.orderBy("displayOrder").asc();
		List<UnitInfo> units = unitInfoMapper.selectByExample(unitExample);
		// 判断下级机构是否为叶子节点
		if (null != units && units.size() > 0) {
			List<Long> uids = new ArrayList<Long>();
			for (UnitInfo unit : units) {
				uids.add(unit.getUnitId());
			}
			List<Long> unitChildrenCounts = unitInfoMapper.selectUnitChildrenCount(uids,unitTypeIDs);
			List<Long> unitRolesCOunts = roleInfoMapper.selectUnitRoleCount(uids);
			for (UnitInfo u : units) {
				QkTreeNode node = new QkTreeNode(u.getUnitId(), u.getUnitName());
				node.setIcon("fa fa-university");
				node.setSelectable(true);
				node.getData().put("code", u.getUnitCode());
				node.getData().put("type", "U");
				node.setLeaf(true);
				if (null != unitChildrenCounts && unitChildrenCounts.contains(u.getUnitId())) {
					node.setLeaf(false);
				}
				if (null != unitRolesCOunts && unitRolesCOunts.contains(u.getUnitId())) {
					node.setLeaf(false);
				}
				childrens.add(node);
			}
		}
		if (nodes.size() != 1) {
			roles.addAll(childrens);
			return roles;
		} else {
			List<QkTreeNode> c = nodes.get(0).getChildren();
			c.addAll(roles);
			c.addAll(childrens);
		}
		return nodes;
	}

	@Override
	public RoleInfo load(long roleId) {
		return roleInfoMapper.selectByPrimaryKey(roleId);
	}

	@Override
	public long delete(long roleId) {
		Example rsExample = new Example(RoleResources.class);
		Example.Criteria rsCriteria = rsExample.createCriteria();
		rsCriteria.andEqualTo("roleId", roleId);
		humanRoleResourcesMapper.deleteByExample(rsExample);

		Example hrExample = new Example(HumanRole.class);
		Example.Criteria hrCriteria = hrExample.createCriteria();
		hrCriteria.andEqualTo("roleId", roleId);
		humanRoleMapper.deleteByExample(hrExample);

		roleInfoMapper.deleteByPrimaryKey(roleId);

		return roleId;
	}

	@Override
	public RoleInfo saveUpdate(RoleInfo roleInfo) {
		long roleId = roleInfo.getRoleId();
		if (roleId > 0) {
			roleInfo.setDeleteFlag(0);
			roleInfoMapper.updateByPrimaryKeySelective(roleInfo);
		} else {
			roleId = roleInfo.getRoleId();
			roleInfo.setRoleId(roleId);
			roleInfo.setCreateTime(new Date());
			roleInfo.setDisplayOrder((int) roleId);
			roleInfoMapper.insert(roleInfo);
		}
		return roleInfo;
	}

	@Override
	public List<RoleInfo> search(String name) {
		Example hrExample = new Example(RoleInfo.class);
		Example.Criteria hrCriteria = hrExample.createCriteria();
		hrCriteria.andLike("roleName", "%" + name + "%");
		hrCriteria.andLike("unitCode", SessionHelper.get().getUnitCode() + "%");
		Page<RoleInfo> rolesPage = PageHelper.startPage(1, 20).doSelectPage(() -> {
			roleInfoMapper.selectByExample(hrExample);
		});
		return rolesPage.getResult();
	}

	@Override
	public List<RoleInfo> findRolesByUnitId(long id) {
		Example hrExample = new Example(RoleInfo.class);
		Example.Criteria hrCriteria = hrExample.createCriteria();
		hrCriteria.andEqualTo("unitId", id);
		return roleInfoMapper.selectByExample(hrExample);
	}

	@Override
	public RoleInfo showAdd(long unitId) {
		UnitInfo u = unitInfoMapper.selectByPrimaryKey(unitId);
		RoleInfo roleInfo = new RoleInfo();
		roleInfo.setUnitId(u.getUnitId());
		roleInfo.setUnitCode(u.getUnitCode());
		roleInfo.setUnitName(u.getUnitName());
		roleInfo.setCreateTime(new Date());
		return roleInfo;
	}

	@Override
	public RoleInfo saveUpdateRole(RoleInfo role) {
		if (role.getRoleId() > 0) {
			roleInfoMapper.updateByPrimaryKey(role);
		} else {
			long roleId = role.getRoleId();
			role.setRoleId(roleId);
			roleInfoMapper.insertSelective(role);
		}
		return role;
	}

	@Override
	public List<HumanInfo> getHumanByRole(long roleId) {
		return humanInfoMapper.findHumanByRole(roleId);
	}

	@Override
	public long saveUpdateRoleHuman(HumanRoleForm form) {
		Example exp = new Example(HumanRole.class);
		Example.Criteria cri = exp.createCriteria();
		cri.andEqualTo("roleId", form.getHumanRoleId());
		humanRoleMapper.deleteByExample(exp);
		for (Long humanId : form.getIds()) {
			HumanRole hr = new HumanRole();
			hr.setRoleId(form.getHumanRoleId());
			hr.setHumanId(humanId);
			humanRoleMapper.insert(hr);
		}
		return form.getHumanRoleId();
	}

	@Override
	public Quokka loadRoleResources(long roleId) {
		Quokka result = new Quokka(true);
		// 移动端子系统
		// List<Long> sysAuthority =
		// roleSysRightMapper.findRoleSysAuthority(roleId);
		// result.getDataMap().put("system", sysAuthority.toArray(new
		// Long[sysAuthority.size()]));
		// 平台端资源权限
		Example example = new Example(RoleResources.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("roleId", roleId);
		List<RoleResources> roleResources = humanRoleResourcesMapper.selectByExample(example);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("resource", roleResources);
		result.setData(map);
		return result;
	}

	@Override
	public long saveUpdateRoleResources(HumanRoleResourcesForm form) {
		Example example = new Example(RoleResources.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("roleId", form.getRoleId());
		humanRoleResourcesMapper.deleteByExample(example);
		Set<RoleResources> roleResources = new HashSet<RoleResources>();
		for(RoleResources rr : form.getResources()){
			rr.setRoleId(form.getRoleId());
			roleResources.add(rr);
		}
		final List<RoleResources> roleResList = new ArrayList<RoleResources>(roleResources);
		jdbcTemplate.batchUpdate("insert into role_resources values (?, ?, ?, ?)", new BatchPreparedStatementSetter() {
			@Override
			public void setValues(PreparedStatement ps, int i) throws SQLException {
				RoleResources r = roleResList.get(i);
				ps.setLong(1, r.getRoleId());
				ps.setLong(2, r.getResId());
				ps.setInt(3, r.getResType());
				ps.setInt(4, r.getPartialSelect());
			}
			@Override
			public int getBatchSize() {
				return roleResources.size();
			}
		});
		return form.getRoleId();
	}

	@Override
	public List<Long> loadRoleIds(Long humanId) {
		return roleInfoMapper.loafRoleIds(humanId);
	}

}
